<template>
  <div class="faceBody">
    <div class="faceContent">
      <div class="header">
        <div>
          <span class="hd-title">智能人脸考勤系统</span>
          <div class="facePaner">
            <div :class="tabs1 ? 'active type' : 'type'" @click="changeTabs(1)">人脸考勤签到</div>
            <div :class="tabs2 ? 'active type' : 'type'" @click="changeTabs(2)">人脸信息采集</div>
          </div>
        </div>
        <div style="color: #a1d9ff; font-size: 18px; cursor: pointer" @click="visible = true">
          <a-icon type="question-circle" />
        </div>
      </div>
      <audio  controls="controls" preload="auto" :src="signinMp3" ref="audioin" v-show="false"></audio>
      <audio  controls="controls" preload="auto" :src="signoutMp3" ref="audioout" v-show="false"></audio>
      <div class="center">
        <div class="faceDetect">
          <div class="faceBox">
            <div class="bag" v-show="!isAttendance">
              <div class="box">
                <img src="~@/assets/img/face/face.png" style="width: 374px; height: 374px" />
                <!-- <img src="https://image.xiaomaiketang.com/xm/XFNPfSNNDF.png" />
                <img class="imgBar" src="https://image.xiaomaiketang.com/xm/Ws33RCwHWp.png" /> -->
                <a-button type="danger" @click="startAttend">开始考勤</a-button>
              </div>
            </div>
            <div class="bag noPadding" v-show="isAttendance" style="position: relative">
              <video id="myVideo" muted loop playsinline @loadedmetadata="fnRunFaceLandmark" />
              <!-- videoWidth: 890,
      videoHeight: 580, -->
              <canvas
                id="myCanvas"
                style="position: absolute; top: 0; left: 0"
                :width="videoWidth"
                :height="videoHeight"
              />
            </div>
          </div>
        </div>
        <div class="rightBox" v-if="tabs1">
          <p class="title">学员考勤列表</p>
          <div class="list" v-if="student_list_face.length > 0 && isAttendance">
            <div class="face-item" v-for="(item, index) in student_list_face" :key="index" :class="{ mt12: index > 0 }">
              <div class="left-box">
                <img
                  :src="item.face_pic"
                  alt=""
                  style="width: 50px; height: 50px; border-radius: 4px; margin-right: 8px"
                />
              </div>
              <div class="right-box">
                <div class="sign-info">
                  <span style="font-family: PingFangSC">{{ item.student_name }}</span>
                  <a-tag color="#42CC8B" v-if="item.type == 1"> 签到 </a-tag>
                  <a-tag color="#829EE4" v-if="item.type == 2"> 签退 </a-tag>
                </div>
                <div style="margin-top: 4px; font-family: PingFangSC; color: #fff">{{ item.time | formatDate }}</div>
              </div>
            </div>
          </div>
          <p class="nostart" v-if="!isAttendance">等待考勤中...</p>
          <a-button class="stopBtn" @click="fnClose()" v-else>停止考勤</a-button>
        </div>
        <div class="rightBox" v-if="tabs2">
          <div style="margin-bottom: 10px; color: #fff">选择学员进行人脸采集</div>
          <div>
            <!-- <a-select v-model="student_id" style="width: 258px" placeholder="选择学员进行人脸采集">
              <a-select-option
                :value="item.id"
                v-for="(item, index) in student_list"
                :key="index"
                @click="getStudentInfo(item)"
              >
                {{ item.name }}
              </a-select-option>
            </a-select> -->
            <a-select
              show-search
              allowClear
              v-model="student_id"
              placeholder="选择学员进行人脸采集"
              style="width: 258px"
              :show-arrow="false"
              :filter-option="false"
              :not-found-content="null"
              @search="searchStudent"
              :defaultActiveFirstOption="false"
            >
              <a-select-option
                v-for="(item, index) in student_list"
                :key="index"
                :value="item.id"
                @click="getStudentInfo(item)"
              >
                {{ item.name }}
              </a-select-option>
            </a-select>
          </div>
          <div class="studentInfoList" v-if="studentInfo">
            <div style="margin-bottom: 10px" class="studentName">
              <span style="margin-right: 5px">{{ studentInfo.name }}</span>
              <span v-if="studentInfo.main_phone">{{ studentInfo.main_phone }}</span>
            </div>
            <div class="noimg" :class="{ pading: studentInfo.faces.length > 1 }">
              <!--  -->
              <!-- <div v-if="studentInfo.faces.length < 2 && studentInfo.faces.length > 0" style="position: relative">
                <img
                  :src="imgSrc || studentInfo.faces[0].face_pic"
                  alt=""
                  style="display: block; width: 100%; height: 100%"
                />
                <a-icon
                  type="close"
                  style="position: absolute; right: 5px; top: 8px; color: #ff8651"
                  @click="clickDelete(item)"
                />
              </div> -->

              <img
                :src="imgSrc"
                alt=""
                v-if="studentInfo.faces.length < 2 && imgSrc"
                style="display: block; width: 100%; height: 100%"
              />
              <div v-else-if="studentInfo.faces.length > 0">
                <div
                  v-for="(item, index) in studentInfo.faces"
                  :key="index"
                  style="position: relative"
                  :class="{ mt12: index == 1 }"
                >
                  <img :src="item.face_pic" alt="" style="display: block; width: 100%; height: 100%" />
                  <a-icon
                    type="close"
                    style="position: absolute; right: 5px; top: 8px; color: #fff"
                    @click="clickDelete(item)"
                  />
                </div>
              </div>
              <div v-else class="noface">
                <img src="~@/assets/img/face/user.png" alt="" class="moren" />
                <div>未采集人脸</div>
              </div>
            </div>
          </div>
          <div style="margin-top: 12px" v-if="studentInfo && isVideo">
            <div v-if="imgSrc && studentInfo.faces.length < 2">
              <a-button @click="setImage()" style="margin-right: 10px; border: 1px solid #fc5841; color: #fc5841">
                重新拍摄
              </a-button>
              <a-button type="danger" @click="submit"> 确认提交 </a-button>
            </div>

            <a-button type="danger" @click="setImage()" v-else> 拍摄 </a-button>
          </div>
          <!-- <div class="">
            
          </div> -->
        </div>
      </div>

      <!-- <div class="rule">
        <div class="title_rule">注意事项：</div>
        <p>
          1. 请使用谷歌/火狐浏览器，否则不能进行人脸考勤
          <a target="_blank" href="http://www.chromeliulanqi.com/">
            下载谷歌浏览器&gt;
            <span class="recommend">推荐</span>
          </a>
          <a target="_blank" href="https://www.firefox.com.cn/">下载火狐浏览器&gt;</a>
        </p>
        <p>2. 使用前请检查摄像设备是否已经正确链接</p>
        <p>3. 学员需先完成人脸信息采集，否则不能进行人脸考勤</p>
        <p>4. 九岁以下小孩，建议每三个月更新一次照片</p>
        <p>5. 部分电脑自带的浏览器驱动无法兼容，请根据电脑型号下载驱动</p>
      </div> -->
    </div>
    <a-modal title="注意事项" :visible="visible" :footer="null" @cancel="visible = false">
      <div class="title_rule">注意事项：</div>
      <p>
        1. 请使用谷歌/火狐浏览器，否则不能进行人脸考勤
        <a target="_blank" href="http://www.chromeliulanqi.com/">
          下载谷歌浏览器&gt;
          <span class="recommend">推荐</span>
        </a>
        <a target="_blank" href="https://www.firefox.com.cn/">下载火狐浏览器&gt;</a>
      </p>
      <p>2. 使用前请检查摄像设备是否已经正确链接</p>
      <p>3. 学员需先完成人脸信息采集，否则不能进行人脸考勤</p>
      <p>4. 九岁以下小孩，建议每三个月更新一次照片</p>
      <p>5. 部分电脑自带的浏览器驱动无法兼容，请根据电脑型号下载驱动</p>
    </a-modal>
  </div>
</template>

<script>
import { studentList, faceCreate, faceClock, faceDelete } from '@/api/face'
import * as faceapi from 'face-api.js'
export default {
  created() {
    if (sessionStorage.getItem('store')) {
      this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('store'))))
    }
  },
  data() {
    return {
      visible: false,
      tabs1: true,
      tabs2: false,
      isAttendance: false,
      thisCancas: null,
      Context: null,
      thisVideo: null,
      videoWidth: 890,
      videoHeight: 580,
      nets: 'tinyFaceDetector',
      options: null,
      videoEl: null,
      canvasEl: null,
      withBoxes: true,
      timeout: 0,
      detectFace: 'detectSingleFace',
      constraints: {
        audio: false,
        video: { width: 890, height: 580, transform: 'scaleX(-1)' },
      },
      student_list_face: [],
      time1: 0,
      studentInfo: undefined,
      student_id: undefined,
      student_list: [],
      imgSrc: '',
      isVideo: true,
      timer: null,
      signinMp3:require('@/assets/mp3/signin.mp3'),
      signoutMp3:require('@/assets/mp3/signout.mp3'),
      mp3Url:null
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.fnInit()
    })
    if (this.$route.query.student_id) {
      this.tabs1 = false
      this.tabs2 = true
      this.isAttendance = true
      this.startAttend()
      this.delaultStudent()
      this.student_id = Number(this.$route.query.student_id)
    }
  },
  methods: {
    async fnInit() {
      await faceapi.nets[this.nets].loadFromUri('/models') // 算法模型
      await faceapi.loadFaceLandmarkModel('/models') // 轮廓模型
      // await faceapi.loadFaceExpressionModel('/models') // 表情模型
      // await faceapi.loadAgeGenderModel('/models') // 年龄模型
      // 根据模型参数识别调整结果
      this.options = new faceapi.TinyFaceDetectorOptions({
        inputSize: 512, // 160 224 320 416 512 608
        scoreThreshold: 0.5, // 0.1 ~ 0.9
      })
      this.videoEl = document.getElementById('myVideo')
      this.canvasEl = document.getElementById('myCanvas')
      this.Context = this.canvasEl.getContext('2d')
    },
    changeTabs(e) {
      if (e == 1) {
        this.fnClose()
        this.tabs1 = true
        this.tabs2 = false
        this.isAttendance = false
      }
      if (e == 2) {
        this.fnClose()
        this.tabs1 = false
        this.tabs2 = true
        this.isAttendance = true
        this.startAttend()
        // this.delaultStudent()
      }
    },
    startAttend() {
      this.isAttendance = true
      if (typeof window.stream === 'object') return
      clearTimeout(this.timeout)
      this.timeout = setTimeout(() => {
        clearTimeout(this.timeout)
        navigator.mediaDevices.getUserMedia(this.constraints).then(this.fnSuccess).catch(this.fnError)
      }, 300)
    },
    // 成功启动视频媒体流
    fnSuccess(stream) {
      console.log(stream)
      window.stream = stream // 使流对浏览器控制台可用
      this.videoEl.srcObject = stream
      this.videoEl.play()
      this.isVideo = true
    },
    // 失败启动视频媒体流
    fnError(error) {
      this.isVideo = false
      this.$message.warning('视频媒体流获取错误')
    },
    //提交人脸
    studentFaceInfo() {
      this.Context.drawImage(this.videoEl, 0, 0, this.videoWidth, this.videoHeight)
      // 获取图片base64链接
      var image = this.canvasEl.toDataURL('image/jpeg', 0.7)
      faceClock({ url: image, school_id: this.$store.state.user.school })
        .then((res) => {
          clearTimeout(this.time1)
          if (res) {
            this.student_list_face.unshift(res)
            if(res.type==1){
              this.$refs.audioin.play()
            }
            if(res.type==2){
              this.$refs.audioout.play()
            }
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    // 人脸面部勘探轮廓识别绘制
    async fnRunFaceLandmark() {
      console.log('RunFaceLandmark')
      if (this.videoEl.paused) return clearTimeout(this.timeout)
      // 识别绘制人脸信息
      if (this.tabs1) {
        const result = await faceapi[this.detectFace](this.videoEl, this.options).withFaceLandmarks()
        if (result && !this.videoEl.paused) {
          const dims = faceapi.matchDimensions(this.canvasEl, this.videoEl, true)
          const resizeResult = faceapi.resizeResults(result, dims)
          this.withBoxes
            ? faceapi.draw.drawDetections(this.canvasEl, resizeResult)
            : faceapi.draw.drawFaceLandmarks(this.canvasEl, resizeResult)
          this.time1 = setTimeout(() => {
            this.studentFaceInfo()
          }, 4000)
        } else {
          this.canvasEl.getContext('2d').clearRect(0, 0, this.canvasEl.width, this.canvasEl.height)
        }
        this.timeout = setTimeout(() => this.fnRunFaceLandmark(), 2000)
      }
    },
    // 结束摄像头视频媒体
    fnClose() {
      this.isAttendance = false
      this.canvasEl.getContext('2d').clearRect(0, 0, this.canvasEl.width, this.canvasEl.height)
      this.videoEl.pause()
      clearTimeout(this.timeout)
      if (typeof window.stream === 'object') {
        window.stream.getTracks().forEach((track) => track.stop())
        window.stream = ''
        this.videoEl.srcObject = null
      }
    },
    delaultStudent() {
      studentList({ school_id: this.$store.state.user.school })
        .then((res) => {
          this.student_list = res
          if (this.$route.query.student_id) {
            res.forEach((item) => {
              if (item.id == this.$route.query.student_id) {
                this.studentInfo = item
              }
            })
          }
        })
        .catch((err) => {
          this.$message.error(err.data.message || '学员获取失败，请刷新后重试')
        })
    },
    //采集人脸 学员列表
    searchStudent(val) {
      let that = this
      if (this.timer != null) {
        clearTimeout(this.timer)
        this.timer = null
      } else {
        this.timer = setTimeout(function () {
          studentList({
            school_id: that.$store.state.user.school,
            name: val,
          }).then((res) => {
            that.timer = null
            that.student_list = res
          })
        }, 500)
      }
    },
    //录入人脸
    getStudentInfo(data) {
      this.studentInfo = data
      // if (data.faces.length > 0) {
      //   this.imgSrc = data.faces[0].face_pic
      // } else {
      //   this.imgSrc = ''
      // }
    },
    //拍照
    setImage() {
      var _this = this
      //canvas画图
      if (this.studentInfo.faces.length == 2) {
        this.$message.warning('每个学员最多录入2张照片，请先删除一张')
        return
      }
      _this.Context.drawImage(_this.videoEl, 0, 0, 890, 580)
      // 获取图片base64链接
      var image = this.canvasEl.toDataURL('image/jpeg', 0.7)
      _this.imgSrc = image
      this.fnClose()
      this.startAttend()
      // let pic = this.dataURLtoFile(image, '123')
    },
    submit() {
      faceCreate({ url: this.imgSrc, school_id: this.$store.state.user.school, student_id: this.studentInfo.id })
        .then((res) => {
          this.$message.success('录入成功')
          this.imgSrc = ''
          this.getStudentInfo(res)
        })
        .catch((err) => {
          this.$message.error(err.data.message || '录入失败，请刷新后重试')
        })
    },
    clickDelete(data) {
      let that = this
      this.$confirm({
        title: '确定要删除该照片吗?',
        // content: (h) => <div style="color:red;">Some descriptions</div>,
        onOk() {
          faceDelete({
            school_id: that.$store.state.user.school,
            student_id: that.studentInfo.id,
            face_token: data.face_token,
          })
            .then((res) => {
              that.$message.success('删除成功')
              that.getStudentInfo(res)
            })
            .catch((err) => {
              that.$message.error(err.data.message || '删除失败，请刷新后重试')
            })
        },
        onCancel() {
          console.log('Cancel')
        },
        class: 'test',
      })
    },
  },
}
</script>
<style>
.ant-select-selection {
  background: #273d72 !important;
  border: 1px solid #273d72;
}
.ant-select-selection__placeholder {
  color: #7691d2 !important;
}
.ant-select-selection-selected-value {
  color: #7691d2 !important;
}
.ant-select-search__field__mirror {
  color: #7691d2 !important;
}
.ant-select-search__field {
  color: #7691d2 !important;
}
.ant-select-selection__clear {
  background: #273d72 !important;
  color: #7691d2 !important;
}
</style>
<style lang="scss" scoped>
@import './face.scss';
.rightBox {
  width: 280px;
  height: 580px;
  background: #fff;
  margin-left: 20px;
  float: left;
  padding: 10px;
  overflow: auto;
  position: relative;
}
.studentInfoList {
  background: #273d72;
  border-radius: 4px;
  margin-top: 12px;
  padding: 6px 12px;
  .studentName {
    color: #fff;
  }
}
.noimg {
  text-align: center;

  // padding-top: 24px;
  .moren {
    width: 78px;
    height: 84px;
    display: block;
    margin: 0 auto;
  }
  .noface {
    height: 150px;
    background: #0d122b;
    font-size: 14px;
    font-family: PingFangSC;
    font-weight: 400;
    color: #999;
    line-height: 20px;
    margin-top: 12px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }
}
.pading {
  padding-top: 0;
}
.face-item {
  display: flex;
  color: #fff;
  height: 80px;
  padding: 10px;
  background: #141c42;
  align-items: center;
  .left-box {
    width: 60px;
    height: 48px;
  }
  .right-box {
    flex: 1;
  }
}
.sign-info {
  display: flex;
  justify-content: space-between;
}
.mt12 {
  margin-top: 12px;
}
</style>